package com.itheima.reggie.controller;

import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * @author ：石破天
 * @date ：Created in 2022年05月26日
 * @description ：
 *   处理公共业务的 处理器
 *       上传下载 不属于某个模块 整个项目所有模块上传下载 我都处理
 * @version: 1.0
 */
@RestController
@Slf4j
@RequestMapping("/common")
public class CommonController {

    // 去配置文件中 找到 路径变量 赋值
    @Value("${reggie.path}")
    private String basePath;

    /**
     * 实现文件上传的处理
     *    1:上传的文件 是不是应该存在服务器的一个固定位置,
     *      下载还得找这个位置.
     *      先把上传的位置,定义在全局变量上(yml中)
     */
    @PostMapping("/upload")
    public R<String> upload(MultipartFile file){
        log.info("我们看一下这是个嘛..."+file);
        //获取上传文件的原始名字
        String originalFilename = file.getOriginalFilename();
        log.info("file就是上传的文件信息,file的名字叫啥呢"+originalFilename);
        //  原始名字  originalFilename    songxiaobao.jpg
        // 大家能不能根据以前学习的 把 后缀名 .jpg截取出来
//        originalFilename.lastIndexOf(".")// .最后一次出现的索引
        //  是不是从.的最后的索引  进行截取
        String fileHouzhui = originalFilename.substring(originalFilename.lastIndexOf("."));
               // suffix 后缀名

        // 我们要把图片存到服务上 图片的名字是随机的 但是图片的类型 必须和原始文件一致
//        UUID.randomUUID().toString()  新的功能  生成随机的字符串
        // 生成的随机字符串要作为什么出现呢?
        String fileName =  UUID.randomUUID().toString()+fileHouzhui;//   名字.后缀

        // 是不是想把   MultipartFile file  上传文件里面的数据 转换到 我们自己的文件里面
        // 自己的文件在哪放着呢?  yml配置了
        // 这个 basePath 有可能不存在
        File dir = new File(basePath);//把文件的基本目录进行封装 判断它是否存在
        if(!dir.exists()){//不存在
            //创建出来
            dir.mkdirs();
        }
        //我们能不能指定服务器 当前要存储文件的路径了
        File uploadFile = new File(dir, fileName);//我们接收上传文件的  新文件构建出来
        //  这个新文件的数据 来自 上传的数据   MultipartFile file
        //  按照以前方式 是不是边读编写......
        //  现在高级了  直接通过   MultipartFile file
        try {
            file.transferTo(uploadFile);//把 上传的数据 转换到 新文件中
                 // 底层是  copy(输入流,输出流)
            // 如果没异常 搞定了
            return R.success(fileName);//因为前端要你的  文件在服务器的名字
        } catch (IOException e) {
            e.printStackTrace(); // 你的新文件如果不存在呢?  有权限问题呢,都会在这里爆出...
        }
         return R.error("程序上传过程中遇到问题了");

    }


    /**
     *  后端要出预览业务    就是 下载
     *       需要参数
     *          前端传过来的文件名
     *          响应对象
     *       返回值写什么?  void
     *          我们以前写返回值,是不是把数据转换成json写响应体中.....
     *          现在 是不是我们自己手动用响应对象 写字节数据了 ,那还需不需要返回值了?
     *
     *    怎么处理下载呢
     *       是不是要根据用户需要的 文件名名字 ,,,,找到这个文件
     *       把文件数据读到程序中.
     *       通过  响应对象的字节输出流  写到浏览器
     */
    @GetMapping("/download")
    public void download(String name, HttpServletResponse response){
        log.info("[进行文件下载,下载的文件名 name:{}]",name);
        //先读后写
        try{
            // 要下载的文件--要读的文件在哪?  basePath 下的 name文件
            File file = new File(basePath,name);
            // 这个要下载的文件是不是需要 字节输入流去读? 需要
            FileInputStream in = new FileInputStream(file);
            //读到的数据写哪里 写到 response字节输出流
            ServletOutputStream out = response.getOutputStream();

            //开始 边读编写  注意  你写的内容是不是一个图片 这个是时候
            //在响应头上告知 浏览器 要以图片形式打开
            response.setContentType("image/jpeg");//告知浏览器打开形式  设置响应数据类型

            //边读编写  --  忘了先复制  晚上十点在问在学
            int len = 0;
            byte[] buffer = new byte[8*1024];
            while(((len=in.read(buffer))!=-1)){
                //写出去
                out.write(buffer,0,len);//读多少写多少
            }
           //释放资源
            out.close();//写不写都行 因为  response对象会自动管理
            in.close();


        }catch (IOException e){
            System.out.println("测试问题不重要,将来开发图片都有");
        }
    }
}
